#region Using Statements
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

using TheTrench;
using TheTrench.Properties;
using Xfinity;
using Xfinity.Entities;
using Xfinity.Engine;
using Xfinity.Engine.Plugins;
using Xfinity.Loaders;
using Xfinity.Weapons;
using Xfinity.ParticleSystems;
using Xfinity.Console;
using Xfinity.Helpers;
using Xfinity.Settings;
using Xfinity.Materials;
#endregion

namespace TheTrench
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Trench : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        ContentManager content;
        static GameManager gm;

        bool fullscreen = false;
        public Trench()
        {
            Trace.WriteLine(Process.GetCurrentProcess().StartInfo.Arguments, "Command line arguments");
            Debug.WriteLine(Assembly.GetExecutingAssembly().FullName);
            graphics = new GraphicsDeviceManager(this);
            graphics.PreparingDeviceSettings +=
    new EventHandler<PreparingDeviceSettingsEventArgs>(
                        graphics_PreparingDeviceSettings);
            content = new ContentManager(Services);
            gm = new GameManager(this);
            Components.Add(new FpsCounter(this));
            try
            {
                graphics.SynchronizeWithVerticalRetrace = Xfinity.Settings.EngineSettings.VSync;
                graphics.PreferMultiSampling = Xfinity.Settings.EngineSettings.AntiAliasing;
                graphics.PreferredBackBufferHeight = 960;

                graphics.PreferredBackBufferWidth = 1280;
                //graphics.IsFullScreen = true;
                graphics.ApplyChanges();
                this.IsFixedTimeStep = false;
                IMaterialDescription d;
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.ToString());
                throw;
            }
        }
        private void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
            //e.GraphicsDeviceInformation.CreationOptions =
            //    CreateOptions.SoftwareVertexProcessing;
            //e.GraphicsDeviceInformation.DeviceType =
            //    DeviceType.Reference;
            //e.GraphicsDeviceInformation.PresentationParameters.MultiSampleType =
            //    MultiSampleType.None;
        }
        [BindCommand(Keys.F2, "ShowSettings")]
        private static void ShowSettings(string[] commands)
        {
            SettingsPage page = new SettingsPage();//.Show(); GameManager.Paused = true;
            page.SetPause(gm);
            page.Show();
            GameManager.Paused = true;
        }
        [BindCommand(Keys.Escape, "Quit")]
        private static void Quit(string[] commands)
        {
            GameManager.Game.Exit();
        }


        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            foreach (IGameComponent gc in Components)
            {
                Entity ent = gc as Entity;
                if (ent != null)
                {
                    Trace.WriteLine(ent.Name + ".", "Entity loaded");
                }
            }

            if (fullscreen)
            {
                graphics.PreferredBackBufferHeight = graphics.GraphicsDevice.DisplayMode.Height;
                graphics.PreferredBackBufferWidth = graphics.GraphicsDevice.DisplayMode.Width;
                graphics.ToggleFullScreen();
            }
            //graphics.GraphicsDevice.PresentationParameters.

            if (Xfinity.Settings.EngineSettings.AntiAliasing)
            {
                graphics.GraphicsDevice.PresentationParameters.MultiSampleType = Xfinity.Settings.EngineSettings.AASampleType;
            }

            graphics.ApplyChanges();
            base.Initialize();
        }

        /// <summary>
        /// Load your graphics content.  If loadAllContent is true, you should
        /// load content from both ResourceManagementMode pools.  Otherwise, just
        /// load ResourceManagementMode.Manual content.
        /// </summary>
        /// <param name="loadAllContent">Which type of content to load.</param>
        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {
                GameManager.LoadPlayerCharacter();
                gm.CreateNpcCharacter(@"Content\Models\Characters\M16_CAR15", "Supr-Neva");
                Window.Title = "The Trench"; // FIGURE IT OUT YOURSELF
            }

        }

        /// <summary>
        /// Unload your graphics content.  If unloadAllContent is true, you should
        /// unload content from both ResourceManagementMode pools.  Otherwise, just
        /// unload ResourceManagementMode.Manual content.  Manual content will get
        /// Disposed by the GraphicsDevice during a Reset.
        /// </summary>
        /// <param name="unloadAllContent">Which type of content to unload.</param>
        protected override void UnloadGraphicsContent(bool unloadAllContent)
        {
            if (unloadAllContent == true)
            {
                content.Unload();
            }
        }
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (!GameManager.Paused)
            {
                base.Update(gameTime);
                GameManager.CurrentState.Update(gameTime);
                //emitter.Emit(10);
            }
            //GC.Collect(0);
        }

        //private Texture2D background;

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GameManager.CurrentState.Draw(gameTime);
            //manager.WorldViewProjection = GraphicsHelper.ActiveCamera.ViewProjectionMatrix;
            base.Draw(gameTime);
        }
    }
}